/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#include "AdtFile.h"

namespace PQGameCore
{
	AdtFile::~AdtFile(void)
	{
	}

	AdtFile::AdtFile(PQEngine::FileBase* f)
	{
		_file=f;

		memset(mcins, 0, sizeof(adt_mcin)*256);
		init(f);
	}

	void AdtFile::init(PQEngine::FileBase *f)
	{

		_file=f;
		char fourcc[5];
		int size=0;

		f->open();
		f->read(fourcc,4);
		f->read(&size, 4);
		flipcc(fourcc);
		fourcc[4] = 0;
		
		//read version
		if (strncmp(fourcc, "MVER", 4) == 0) {
			f->read(&version, 4);
		}

		
		initMHDR(f);//read header
		initMCIN(f);//read chunk info
		initMTEX(f);//read texture names
		initMMDX(f);//read model names
		initMWMO(f);//read wmo names
		initMDDF(f);//read map doodad def
		initMODF(f);//read map object def

		// read individual map chunks
		for (int i=0; i<16*16; i++) {	
			chunks[i]=new AdtChunkFile(f,i,mcins+i);
		}

		f->close();
	}


	void AdtFile::initMHDR(PQEngine::FileBase *f)
	{
		char fourcc[5];
		int size=0;
		f->read(fourcc,4);
		f->read(&size, 4);
		flipcc(fourcc);
		fourcc[4] = 0;
		header_pos=f->getPosition();
		if (strncmp(fourcc, "MHDR", 4) == 0) {
			f->read(&mhdr,size);
		}else{//shouldn't happen
			assert(true);
		}
	}
	void AdtFile::initMCIN(PQEngine::FileBase *f)
	{
		char fourcc[5];
		int size=0;
		int mcin_pos=header_pos+mhdr.mcin;//
		f->seek(mcin_pos);
		f->read(fourcc,4); // MCIN
		f->read(&size, 4);
		flipcc(fourcc);
		fourcc[4] = 0;
		if (strncmp(fourcc, "MCIN", 4) == 0) {
			assert(size==256*16);
			f->read(mcins,16*256);
		}else{//shouldn't happen
			assert(true);
		}
	}

	void AdtFile::initMTEX(PQEngine::FileBase *f)
	{
		char fourcc[5];
		int size=0;
		int mtex_pos=header_pos+mhdr.mtex;
		f->seek(mtex_pos);
		f->read(fourcc,4); // MTEX
		f->read(&size, 4);
		flipcc(fourcc);
		fourcc[4] = 0;
		if (strncmp(fourcc, "MTEX", 4) == 0) {
			char* names=new char[size+1];
			f->read(names,size);
			names[size]=0;

			char* p=names;
			mtexCount=0;
			while (p<names+size) {
				p+=strlen(p)+1;
				mtexCount++;
			}
			mtexs=new char*[mtexCount];
			p=names;
			int i=0;
			while (p<names+size) {
				mtexs[i++]=p;
				p+=strlen(p)+1;
			}

		}else{//shouldn't happen
			assert(true);
		}
	}
	void AdtFile::initMMDX(PQEngine::FileBase *f)
	{
		char fourcc[5];
		int size=0;
		int mmdx_pos=header_pos+mhdr.mmdx;
		f->seek(mmdx_pos);
		f->read(fourcc,4); // MMDX
		f->read(&size, 4);
		flipcc(fourcc);
		fourcc[4] = 0;
		if (strncmp(fourcc, "MMDX", 4) == 0) {
			char* names=new char[size+1];
			f->read(names,size);
			names[size]=0;

			char* p=names;
			mmdxCount=0;
			while (p<names+size) {
				p+=strlen(p)+1;
				mmdxCount++;
			}
			mmdxs=new char*[mmdxCount];
			p=names;
			int i=0;
			while (p<names+size) {
				mmdxs[i++]=p;
				p+=strlen(p)+1;
			}

		}else{//shouldn't happen
			assert(true);
		}
	}

	void AdtFile::initMWMO(PQEngine::FileBase *f)
	{
		char fourcc[5];
		int size=0;
		int mwmo_pos=header_pos+mhdr.mwmo;
		f->seek(mwmo_pos);
		f->read(fourcc,4); // MMDX
		f->read(&size, 4);
		flipcc(fourcc);
		fourcc[4] = 0;
		if (strncmp(fourcc, "MWMO", 4) == 0) {
			char* names=new char[size+1];
			f->read(names,size);
			names[size]=0;

			char* p=names;
			mwmoCount=0;
			while (p<names+size) {
				p+=strlen(p)+1;
				mwmoCount++;
			}
			mwmos=new char*[mwmoCount];
			p=names;
			int i=0;
			while (p<names+size) {
				mwmos[i++]=p;
				p+=strlen(p)+1;
			}

		}else{//shouldn't happen
			assert(true);
		}
	}

	void AdtFile::initMDDF(PQEngine::FileBase *f)
	{
		char fourcc[5];
		int size=0;
		int mddf_pos=header_pos+mhdr.mddf;
		f->seek(mddf_pos);
		f->read(fourcc,4); // MMDX
		f->read(&size, 4);
		flipcc(fourcc);
		fourcc[4] = 0;
		if (strncmp(fourcc, "MDDF", 4) == 0) {
			mddfCount= (int)size / 36;
			mddfs=new adt_mddf[mddfCount];
			f->read(mddfs,size);
		}else{//shouldn't happen
			assert(true);
		}
	}

	void AdtFile::initMODF(PQEngine::FileBase *f)
	{
		char fourcc[5];
		int size=0;
		int modf_pos=header_pos+mhdr.modf;
		f->seek(modf_pos);
		f->read(fourcc,4); // MODF
		f->read(&size, 4);
		flipcc(fourcc);
		fourcc[4] = 0;
		if (strncmp(fourcc, "MODF", 4) == 0) {
			modfCount= (int)size / 64;
			modfs=new adt_modf[modfCount];
			f->read(modfs,size);
		}else{//shouldn't happen
			assert(true);
		}
	}
}

